/*
 *
 */
package com.zhenhe.core.common.utils.pay.bohai.support;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;

import com.zhenhe.core.common.utils.pay.bohai.BoHaiUtil;

/**
 *  
 */
public class PacUtil {
    public static HostnameVerifier hv = new PacHostnameVerifier();

    public static String hostUrl = "http://221.239.93.138:9081/pacServer/connect.do";

    public static int timeout = 60000;

    public static String CHARSET = "utf-8";

    @SuppressWarnings("deprecation")
	public static String formatData(Map<String, Object> dataMap) {
        log.info("Format data:" + dataMap);

        String xmlStr = null;

        String instSeq = (String) dataMap.get("instSeq");
        String instId = "100099";
        String certId = "1000992014081101";
        String pyrAct = "2000713325000168";
        String pyrNam = "Name2000713325";

        if (null != dataMap.get("instId")) {
            instId = (String) dataMap.get("instId");
        }

        if (null != dataMap.get("certId")) {
            certId = (String) dataMap.get("certId");
        }

        if (null != dataMap.get("pyrAct")) {
            pyrAct = (String) dataMap.get("pyrAct");
        }

        if (null != dataMap.get("pyrNam")) {
            pyrNam = (String) dataMap.get("pyrNam");
        }

        String transType = (String) dataMap.get("transType");

        Date curDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
        String instDate = sdf.format(curDate);

        StringBuffer buf = new StringBuffer("<?xml version='1.0' encoding='");
        buf.append(CHARSET);
        buf.append("'?><Cbhbpac><Message id=\"");
        buf.append(instSeq);
        buf.append("\"><");
        buf.append(transType);
        buf.append("Req id=\"");
        buf.append(transType);
        buf.append("Req\"><version>1.0.1</version>");

        buf.append("<instId>");
        buf.append(instId);
        buf.append("</instId>");

        buf.append("<certId>");
        buf.append(certId);
        buf.append("</certId>");

        buf.append("<serialNo>");
        buf.append(instSeq);
        buf.append("</serialNo>");

        buf.append("<date>");
        buf.append(instDate);
        buf.append("</date>");

        if ("SCSP".equals(transType) || "SCHP".equals(transType)) {
            String pyeAct = (String) dataMap.get("pyeAct");
            String pyeNam = (String) dataMap.get("pyeNam");

            String pyeBnk = (String) dataMap.get("pyeBnk");
            String amt = (String) dataMap.get("amt");
            String postscript = (String) dataMap.get("postscript");

            buf.append("<pyrAct>");
            buf.append(pyrAct);
            buf.append("</pyrAct>");

            buf.append("<pyrNam>");
            buf.append(pyrNam);
            buf.append("</pyrNam>");

            buf.append("<pyeAct>");
            buf.append(pyeAct);
            buf.append("</pyeAct>");

            buf.append("<pyeNam>");
            buf.append(pyeNam);
            buf.append("</pyeNam>");

            buf.append("<pyeBnk>");
            buf.append(pyeBnk);
            buf.append("</pyeBnk>");

            buf.append("<amt>");
            buf.append(amt);
            buf.append("</amt>");

            buf.append("<postscript>");
            buf.append(postscript);
            buf.append("</postscript>");
        }

        if ("SCTQ".equals(transType)) {
            buf.append("<instSeq>");
            buf.append(instSeq);
            buf.append("</instSeq>");
        }

        if ("SCBP".equals(transType) || "SCBT".equals(transType)) {
            String totNum = (String) dataMap.get("totNum");
            String totAmt = (String) dataMap.get("totAmt");

            String fileNam = (String) dataMap.get("fileNam");
            String fileSha1 = (String) dataMap.get("fileSha1");

            buf.append("<pyrAct>");
            buf.append(pyrAct);
            buf.append("</pyrAct>");

            buf.append("<pyrNam>");
            buf.append(pyrNam);
            buf.append("</pyrNam>");

            buf.append("<totNum>");
            buf.append(totNum);
            buf.append("</totNum>");

            buf.append("<totAmt>");
            buf.append(totAmt);
            buf.append("</totAmt>");

            buf.append("<fileNam>");
            buf.append(fileNam);
            buf.append("</fileNam>");

            if (null != fileSha1 && !"".equals(fileSha1)) {
                buf.append("<fileSHA1>");
                buf.append(fileSha1);
                buf.append("</fileSHA1>");
            } else {

                try {
                    FileInputStream fis = new FileInputStream(
                            "/BHIBS/files/cbhbpac/btrn/upload/" + instId + "/"
                                    + fileNam);
                    byte[] fileContent = PacUtil.readAllByteFromStream(fis);
                    String sha1 = DigestUtils.shaHex(fileContent);
                    log.info("Cal SHA1:" + sha1);

                    buf.append("<fileSHA1>");
                    buf.append(sha1);
                    buf.append("</fileSHA1>");

                } catch (Exception e) {
                    log.error("Error while read file !", e);
                }
            }

        }

        if ("SCBR".equals(transType)) {
            String fileNam = (String) dataMap.get("fileNam");
            String termJnlno = (String) dataMap.get("termJnlno");

            buf.append("<fileNam>");
            buf.append(fileNam);
            buf.append("</fileNam>");
            
            buf.append("<termJnlno>");
            buf.append(termJnlno);
            buf.append("</termJnlno>");
        }

        if ("SCBS".equals(transType)) {
            String fileNam = (String) dataMap.get("fileNam");
            String seqNo = (String) dataMap.get("seqNo");
            String termJnlno = (String) dataMap.get("termJnlno");

            buf.append("<fileNam>");
            buf.append(fileNam);
            buf.append("</fileNam>");

            buf.append("<seqNo>");
            buf.append(seqNo);
            buf.append("</seqNo>");
            
            buf.append("<termJnlno>");
            buf.append(termJnlno);
            buf.append("</termJnlno>");

        }
        
        if ("SCRQ".equals(transType)) {
            String sysCd = (String) dataMap.get("sysCd");
            String begDat = (String) dataMap.get("begDat");
            String endDat = (String) dataMap.get("endDat");

            buf.append("<pyrAct>");
            buf.append(pyrAct);
            buf.append("</pyrAct>");

            buf.append("<sysCd>");
            buf.append(sysCd);
            buf.append("</sysCd>");            
            
            buf.append("<begDat>");
            buf.append(begDat);
            buf.append("</begDat>");
            
            buf.append("<endDat>");
            buf.append(endDat);
            buf.append("</endDat>");            
        }

        buf.append("</");
        buf.append(transType);
        buf.append("Req></Message></Cbhbpac>");

        xmlStr = buf.toString();

        return xmlStr;
    }

    public static String issuePac(String sndContent) throws Exception {
        final String contentType = "application/xml;charset=utf-8";
        
        System.out.println("发送：");
        System.out.println(sndContent);
        byte[] content = null;
        try {
            content = sndContent.getBytes(CHARSET);
        } catch (UnsupportedEncodingException e) {
            log.error("Error occur !", e);
        }

        System.getProperties().put("java.protocol.handler.pkgs",
                "com.ibm.net.ssl.www2.protocol");

        URL myUrl = new URL(hostUrl);

        if (log.isInfoEnabled()) {
            log.info(new StringBuffer("Send to ").append(hostUrl)
                    .append(", content :").append(sndContent).toString());
        }

        HttpURLConnection httpConn = (HttpURLConnection) myUrl.openConnection();

        httpConn.setRequestMethod("POST");

        if (httpConn instanceof HttpsURLConnection) {
            HttpsURLConnection httpsConn = (HttpsURLConnection) httpConn;
            httpsConn.setHostnameVerifier(hv);

            X509TrustManager xtm = new PacTrustManager();
            TrustManager mytm[] = { xtm };
            SSLContext ctx = SSLContext.getInstance("SSL");
            ctx.init(null, mytm, new SecureRandom());
            SSLSocketFactory factory = ctx.getSocketFactory();

            httpsConn.setSSLSocketFactory(factory);

        }
        httpConn.addRequestProperty("Content-Type", contentType);

        httpConn.setDoInput(true);
        httpConn.setDoOutput(true);

        httpConn.connect();
        OutputStream out = httpConn.getOutputStream();
        out.write(content);
        out.flush();
        out.close();

        String rspContent = null;

        byte[] rspByte = readAllByteFromStream(httpConn.getInputStream());
        if (null != rspByte) {
            rspContent = new String(rspByte, CHARSET);
            System.out.println("接收：");
            System.out.println(rspContent);
        } else {
            log.debug("can not read any content from server!");
        }

        httpConn.disconnect();
        httpConn = null;
        myUrl = null;

        if (log.isInfoEnabled()) {
            log.info(new StringBuffer("Receive response:").append(rspContent)
                    .toString());
        }

        return rspContent;
    }

    private static byte[] readAllByteFromStream(InputStream is)
            throws Exception {
        byte[] buf = new byte[8072];

        ByteArrayOutputStream baos = new ByteArrayOutputStream(8072);
        int readCount = is.read(buf);
        while (readCount != -1) {
            baos.write(buf, 0, readCount);
            readCount = is.read(buf);
        }

        byte[] rsByte = baos.toByteArray();

        baos.close();
        baos = null;

        return rsByte;

    }

    protected static final Logger log = BoHaiUtil.log;
}